using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using System.Reflection;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Configuration.MiddlewareModules
{
    /// <summary>
    /// 中间件模块注册器
    /// 负责自动发现和配置所有中间件模块
    /// </summary>
    public static class MiddlewareModuleRegistry
    {
        private static readonly List<IMiddlewareModule> _modules = new();
        private static bool _modulesLoaded = false;

        /// <summary>
        /// 配置所有中间件模块
        /// </summary>
        /// <param name="app">应用程序</param>
        /// <param name="configuration">配置对象</param>
        public static void ConfigureAllModules(WebApplication app, IConfiguration configuration)
        {
            if (!_modulesLoaded)
            {
                LoadModules();
                _modulesLoaded = true;
            }

            var isDevelopment = app.Environment.IsDevelopment();
            var isProduction = app.Environment.IsProduction();
            var isFastMode = JGSY.CMS.LowCode.Platform.Infrastructure.Configuration.StartupOptimizations.IsFastStartupEnabled(configuration);

            var applicableModules = _modules
                .Where(m => ValidateEnvironment(m, isDevelopment, isProduction, isFastMode))
                .Where(m => m.ValidateConfiguration(configuration))
                .OrderBy(m => m.Priority)
                .ToList();

            foreach (var module in applicableModules)
            {
                try
                {
                    var stopwatch = System.Diagnostics.Stopwatch.StartNew();
                    module.ConfigureMiddleware(app, configuration);
                    stopwatch.Stop();
                    
                    Infrastructure.Configuration.StartupLogger.LogStartupMilestone($"中间件模块 {module.ModuleName} 配置完成，耗时: {stopwatch.ElapsedMilliseconds}ms");
                }
                catch (Exception ex)
                {
                    Infrastructure.Configuration.StartupLogger.LogStartupError($"中间件模块 {module.ModuleName} 配置失败", ex);
                    throw;
                }
            }
        }

        /// <summary>
        /// 验证中间件是否应该在当前环境下启用
        /// </summary>
        private static bool ValidateEnvironment(IMiddlewareModule module, bool isDevelopment, bool isProduction, bool isFastMode)
        {
            if (isFastMode && !module.EnableInFastMode)
                return false;

            if (isDevelopment && !module.EnableInDevelopment)
                return false;

            if (isProduction && !module.EnableInProduction)
                return false;

            return true;
        }

        /// <summary>
        /// 加载所有中间件模块
        /// </summary>
        private static void LoadModules()
        {
            var moduleTypes = Assembly.GetExecutingAssembly()
                .GetTypes()
                .Where(t => typeof(IMiddlewareModule).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract)
                .ToList();

            foreach (var moduleType in moduleTypes)
            {
                try
                {
                    var module = (IMiddlewareModule)Activator.CreateInstance(moduleType)!;
                    _modules.Add(module);
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException($"无法创建中间件模块实例: {moduleType.Name}", ex);
                }
            }
        }

        /// <summary>
        /// 手动注册中间件模块
        /// </summary>
        /// <param name="module">中间件模块</param>
        public static void RegisterModule(IMiddlewareModule module)
        {
            if (!_modules.Contains(module))
            {
                _modules.Add(module);
            }
        }

        /// <summary>
        /// 获取已注册的中间件模块列表
        /// </summary>
        /// <returns>中间件模块列表</returns>
        public static IReadOnlyList<IMiddlewareModule> GetRegisteredModules()
        {
            if (!_modulesLoaded)
            {
                LoadModules();
                _modulesLoaded = true;
            }
            return _modules.AsReadOnly();
        }
    }
}
